require 'rubygems'
require 'macaddr'
require 'uuidtools'
require 'digest/sha1'

include UUIDTools

class User < ActiveRecord::Base
  # Virtual attribute for the unencrypted password
  has_and_belongs_to_many :roles
  belongs_to             :recommender,:class_name=>"User",:foreign_key => "recommender_id"
  has_many                :addresses
  has_many                :orders
  has_many                :comments
  
  has_and_belongs_to_many :favors,:class_name=>"Product",:join_table => "favorites"
  has_and_belongs_to_many :points,:class_name=>"Product",:join_table => :comments
  attr_accessor :password

  validates_presence_of     :login, :email
  validates_presence_of     :password,                   :if => :password_required?
  validates_presence_of     :password_confirmation,      :if => :password_required?
  validates_length_of       :password, :within => 4..40, :if => :password_required?
  validates_confirmation_of :password,                   :if => :password_required?
  validates_length_of       :login,    :within => 3..40
  validates_length_of       :email,    :within => 3..100
  validates_uniqueness_of   :login, :email, :case_sensitive => false
  before_save :encrypt_password
  
  # prevents a user from submitting a crafted form that bypasses activation
  # anything else you want your user to change should be added here.
  attr_accessible :login, :email, :password, :password_confirmation,:nickname,:sex

  SEX = [
    ["女",0],
    ["男",1]
  ]

  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
  def self.authenticate(login, password)
    u = find_by_login(login) # need to get the salt
    u && u.authenticated?(password) ? u : nil
  end

  # Encrypts some data with the salt.
  def self.encrypt(password, salt)
    Digest::SHA1.hexdigest("--#{salt}--#{password}--")
  end

  # Encrypts the password with the user salt
  def encrypt(password)
    self.class.encrypt(password, salt)
  end

  def authenticated?(password)
    crypted_password == encrypt(password)
  end

  def remember_token?
    remember_token_expires_at && Time.now.utc < remember_token_expires_at 
  end

  # These create and unset the fields required for remembering users between browser closes
  def remember_me
    remember_me_for 2.weeks
  end

  def remember_me_for(time)
    remember_me_until time.from_now.utc
  end

  def remember_me_until(time)
    self.remember_token_expires_at = time
    self.remember_token            = encrypt("#{email}--#{remember_token_expires_at}")
    save(false)
  end

  def forget_me
    self.remember_token_expires_at = nil
    self.remember_token            = nil
    save(false)
  end

  # Returns true if the user has just been activated.
  def recently_activated?
    @activated
  end
  #后来添加的
  def has_role?(role_id)
    self.roles.detect{|role|
      role.id == role_id
    }
  end

  def has_right?(right_id)
    self.roles.detect{|role|
      role.rights.detect{|right|
        right.id == right_id
      }
    }
  end

  def history_products
    Product.find_by_sql(["SELECT DISTINCT p. *
FROM products p, orders o, line_items l
WHERE o.user_id = ?
AND p.id = l.product_id
AND o.id = l.order_id limit 0,4",self.id])
  end
  def self.generate_recommend_code(user_id)
    rc = RecommendCode.new(:user_id=>user_id,:code=>UUIDTools::UUID.random_create().to_s[0,6])
    rc.save
    rc.code
  end
  
  def self.recommend_new(user_hash,rc)
    rc = RecommendCode.find_by_code(rc)
    if rc
      user = self.new(user_hash)
      user.recommender_id = rc.user_id
      self.transaction() do
        user.save
        rc.destroy
      end
      return user
    end
  end

  protected
  # before filter
  def encrypt_password
    return if password.blank?
    self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
    self.crypted_password = encrypt(password)
  end
      
  def password_required?
    crypted_password.blank? || !password.blank?
  end

end
